using System;
using Commons.Utils;

namespace Commons.Models.Timers
{
	public delegate void TimerHandler(Timer sender, bool wasPaused);

	public class Timer : IDisposable, IComparable<Timer>
	{
		public event TimerHandler TimeCompleted;

		public string Id { get; protected set; }
		public object Target { get; protected set; }
		public DateTime Beginning { get; set; }
		public DateTime End { get; set; }

		public TimeSpan Elapsed
		{
			get
			{
				return DateTimeHelper.Current() - Beginning;
			}
		}

		public TimeSpan Remaining
		{
			get
			{
				return End - DateTimeHelper.Current();
			}
		}

		public Timer(string id, object target, DateTime end)
			: this(id, target, DateTimeHelper.Current(), end)
		{
		}

		public Timer(string id, object target, DateTime beginning, DateTime end)
		{
			this.Id = id;
			this.Target = target;
			this.Beginning = beginning;
			this.End = end;
		}

		public void Accelerate(int seconds)
		{
			Accelerate(new TimeSpan(seconds * TimeSpan.TicksPerSecond));
		}

		public void Accelerate(TimeSpan timeSpan)
		{
			End = End.Subtract(timeSpan);
		}

		public void Complete()
		{
			Accelerate(Remaining);
		}

		public bool IsCompleted()
		{
			return Remaining.TotalMilliseconds <= 0;
		}

		public void OnComplete(bool wasPaused)
		{
			if (TimeCompleted != null)
			{
				TimeCompleted(this, wasPaused);
			}

			TimeCompleted = null;
		}

		public void Dispose()
		{
			TimeCompleted = null;
		}
		
		#region IComparable[Timer] implementation
		public int CompareTo (Timer other)
		{
			return End > other.End ? 1 : End == other.End ? 0 : -1;
		}
		#endregion
	}
}

